#ifndef CORE_CALC
#define CORE_CALC

#include "typedef.hpp"
#include "memory.hpp"
#include "page.hpp"

struct IR
{
	uint8_t opcode;
	uint8_t r1, r2, r3;
	uint16_t imm;
};

class CalcCore
{
private:
	MMU &addr_trans;
	Cache &memory;
	uint64_t iregs[32][2];
	uint64_t sregs[4][2];
	uint64_t pages[4];
	uint64_t MAR, MDR;
	Atomic<IOBus *> bus;
	int ID;
	IR command;
	std::pair<bool, uint64_t> proper;
	bool rwStat;
	bool priv;

	void exeI();
	void exeM();
	void exeI_Sys();

	void fetch();
	void decode();
	void execute();
	void memrw();
	void post();

public:
	CalcCore() = default;
	CalcCore(int ID, MMU &mmu, Cache &cache) : ID(ID), addr_trans(mmu), memory(cache), bus(nullptr), command() {}
	~CalcCore() = default;
	void init(Atomic<IOBus *> &);
	void operator()();
	void reset();
	bool isRunning() { return sregs[Status][priv] & Running; }
};

#endif